
#include "main.h"

/****************************************************************************/
/*	Local pre-processor symbols('#define')
****************************************************************************/
/*----AT24C256地址+读写-----------------------------------------------------*/
#define  AT24C256_WRITE		0xA0				/*Write Cmd*/
#define  AT24C256_READ      0xA1				/*Read  Cmd*/
#define  AT24C256_MAX		0x7fff				/*address  max*/

/*----I2C主控模式命令-------------------------------------------------------*/
#define I2C_MASTER_START_SEND				(I2C_I2CMCR_START_Msk | I2C_I2CMCR_RUN_Msk)		/*起始位+从机地址+写+1Byte数据*/
#define I2C_MASTER_SEND						(I2C_I2CMCR_RUN_Msk)							/*发送1Byte数据*/
#define I2C_MASTER_STOP						(I2C_I2CMCR_STOP_Msk)							/*发送停止位*/
#define I2C_MASTER_START_RECEIVE_NACK		(I2C_I2CMCR_START_Msk | I2C_I2CMCR_RUN_Msk)		/*起始位+从机地址+读+1Byte时钟+NACK*/
#define I2C_MASTER_START_RECEIVE_ACK		(I2C_I2CMCR_START_Msk | I2C_I2CMCR_RUN_Msk | I2C_I2CMCR_ACK_Msk) /*起始位+从机地址+读+1Byte时钟+ACK*/
#define I2C_MASTER_RECEIVE_NACK				(I2C_I2CMCR_RUN_Msk)							/*发送读1Byte时钟+NACK*/
#define I2C_MASTER_RECEIVE_ACK				(I2C_I2CMCR_RUN_Msk | I2C_I2CMCR_ACK_Msk)		/*发送读1Byte时钟+ACK*/

/****************************************************************************/
/*	Global variable definitions(declared in header file with 'extern')
****************************************************************************/

/****************************************************************************/
/*	Local type definitions('typedef')
****************************************************************************/

/****************************************************************************/
/*	Local variable  definitions('static')
****************************************************************************/

/****************************************************************************/
/*	Local function prototypes('static')
****************************************************************************/
/*****************************************************************************
 ** \brief	I2C_SendMasterCmd
 **			发送主控命令
 ** \param [in] none
 ** \return  none
 ** \note	 
*****************************************************************************/
void  I2C_SendMasterCmd(uint8_t Cmd)
{
	I2CMCR = Cmd;
}
/*****************************************************************************
 ** \brief	I2C_MasterWriteAddr
 **			主控写从机地址
 ** \param [in] SlaveAddr ：从机地址+读写位R/W
 ** \return  none
 ** \note	 读写位在从机地址的第0位，即7位地址+R/W  
*****************************************************************************/
void  I2C_MasterWriteAddr(uint8_t SlaveAddr)
{
	I2CMSA   = SlaveAddr;
}
/*****************************************************************************
 ** \brief	I2C_MasterWriteBuffer
 **			主控写缓存
 ** \param [in] data
 ** \return  none
 ** \note	 
*****************************************************************************/
void  I2C_MasterWriteBuffer(uint8_t Data)
{
	I2CMBUF = Data;
}
/*****************************************************************************
 ** \brief	I2C_MasterReadBuffer
 **			主控读缓存
 ** \param [in] none
 ** \return  data
 ** \note	 
*****************************************************************************/
uint8_t I2C_MasterReadBuffer(void)
{
	return I2CMBUF;
}

/*****************************************************************************
 ** \brief	 At24c256_write_byte
 **			 写数据到At24C256
 ** \param [in] addr ：地址
**				ch   : 数据
 **            	
 ** \return  -1：超出地址范围 0：写完成
 ** \note  
 *****************************************************************************/
int16_t  At24c256_write_byte(uint16_t addr , uint8_t ch)
{
	volatile int16_t i,j;
	if(addr >AT24C256_MAX)
		return -1;
	else
	{			
		
		I2C_MasterWriteAddr(AT24C256_WRITE);			/*写从机地址+写*/
		I2C_MasterWriteBuffer((addr>>8)& 0xff);			/*写Buffer(高位ROM 地址)*/
		I2C_SendMasterCmd(I2C_MASTER_START_SEND);
		while(!(I2C_GetMasterIntFlag()));				/*等待发送结束*/
		I2C_ClearMasterIntFlag();
								
		I2C_MasterWriteBuffer(addr & 0xff);				/*低位ROM 地址*/
		I2C_SendMasterCmd(I2C_MASTER_SEND);				/*发送Buffer*/
		while(!(I2C_GetMasterIntFlag()));
		I2C_ClearMasterIntFlag();	
		
		I2C_MasterWriteBuffer(ch);							/*写数据*/
		I2C_SendMasterCmd(I2C_MASTER_SEND);
		while(!(I2C_GetMasterIntFlag()));		
		I2C_ClearMasterIntFlag();
		
		I2C_SendMasterCmd(I2C_MASTER_STOP);					/*发送停止位*/
		for(i=2000;i>0;i--)								/*延时确保AT24C256写数据完成*/
			for(j=200;j>0;j--);
	}
	return 0;
}

/********************************************************************************
 ** \brief	 At24c256_read_byte
 **			 从At24C256中读数据
 ** \param [in]  addr : 地址
 **            	
 ** \return  返回8位数据
 ** \note   
 ******************************************************************************/
uint8_t  At24c256_read_byte(uint16_t addr)
{
	unsigned char buffer;
	if(addr > AT24C256_MAX)
		return -1;
	
	I2C_MasterWriteAddr(AT24C256_WRITE);			/*写从机地址+写*/
	I2C_MasterWriteBuffer((addr>>8)& 0xff);			/*写Buffer(高位ROM 地址)*/
	I2C_SendMasterCmd(I2C_MASTER_START_SEND);
	while(!(I2C_GetMasterIntFlag()));				/*等待发送结束*/
	I2C_ClearMasterIntFlag();
							
	I2C_MasterWriteBuffer(addr & 0xff);				/*低位ROM 地址*/
	I2C_SendMasterCmd(I2C_MASTER_SEND);				/*发送Buffer*/
	while(!(I2C_GetMasterIntFlag()));
	I2C_ClearMasterIntFlag();	
	
	I2C_MasterWriteAddr(AT24C256_READ);					/*写从机地址+读*/	
	I2C_SendMasterCmd(I2C_MASTER_START_RECEIVE_NACK);	
		
	while(!(I2C_GetMasterIntFlag()));					/*等待数据接收完成*/
	I2C_ClearMasterIntFlag();							
	buffer=I2C_MasterReadBuffer();						/*读取数据*/
	
	I2C_SendMasterCmd(I2C_MASTER_STOP);					/*发送停止位*/
	return buffer;
}
/********************************************************************************
 ** \brief	 At24c256_read_str
 **			 连续读取At24c256数据
 ** \param [in] addr ：起始地址
 **            	ch	 : 数据保存的容器(数组)  
**				sizevalue: 读取的数据的个数
 ** \return  0/1
 ** \note  	 例：  unsigned char  array[10];			//定义一个10字节的容器
 **	  At24c256_read_str(0x0010, Buffer, 5); //从地址0x0010开始读取5个字节的数据放到数组array中
 ******************************************************************************/
uint16_t At24c256_read_str(uint16_t addr,  uint8_t *ch, uint16_t sizevalue)
{
	volatile int16_t i;
	if(addr > AT24C256_MAX)
		return 0;
	
	I2C_MasterWriteAddr(AT24C256_WRITE);			/*写从机地址+写*/
	I2C_MasterWriteBuffer((addr>>8)& 0xff);			/*写Buffer(高位ROM 地址)*/
	I2C_SendMasterCmd(I2C_MASTER_START_SEND);
	while(!(I2C_GetMasterIntFlag()));				/*等待发送结束*/
	I2C_ClearMasterIntFlag();
							
	I2C_MasterWriteBuffer(addr & 0xff);				/*低位ROM 地址*/
	I2C_SendMasterCmd(I2C_MASTER_SEND);				/*发送Buffer*/
	while(!(I2C_GetMasterIntFlag()));
	I2C_ClearMasterIntFlag();	
	
	I2C_MasterWriteAddr(AT24C256_READ);					/*写从机地址+读*/	
	I2C_SendMasterCmd(I2C_MASTER_START_RECEIVE_ACK);	

	for(i=0;i<sizevalue-2;i++)
	{		
		while(!(I2C_GetMasterIntFlag()));				/*等待数据接收完成*/
		I2C_ClearMasterIntFlag();						
		*ch++ = I2C_MasterReadBuffer();					/*读数据*/
		I2C_SendMasterCmd(I2C_MASTER_RECEIVE_ACK);
	}
	
	while(!(I2C_GetMasterIntFlag()));
	I2C_ClearMasterIntFlag();							
	*ch++ =I2C_MasterReadBuffer();		
	
	while(!(I2C_GetMasterIntFlag()));
	I2C_ClearMasterIntFlag();			
	I2C_SendMasterCmd(I2C_MASTER_RECEIVE_NACK);			/*读取最后一个数据,不发送ACK*/
	*ch =I2C_MasterReadBuffer();														
														
	I2C_SendMasterCmd(I2C_MASTER_STOP);					/*发送停止位*/
	return 1;
}
/****************************************************************************/
/*	Function implementation - global ('extern') and local('static')
****************************************************************************/
/******************************************************************************
 ** \brief	 I2C_Config
 ** \param [in] 
 **            	
 ** \return  none
 ** \note  
 ******************************************************************************/
void I2C_Config(void)
{
	/*
	 (1)开启I2C主控模式
	 */
	 I2C_EnableMasterMode();
	/*
	 (2)设置I2C通讯时钟
	 */	 
	I2C_ConfigCLK(10);							/*设置时钟100K*/
	/*
	(3)设置IO复用
	*/
	 GPIO_SET_MUX_MODE(P25CFG, GPIO_MUX_SCL);			/*SCL*/
	 GPIO_SET_MUX_MODE(P26CFG, GPIO_MUX_SDA);	 		/*SDA*/	 
	 
}





void Seg_san_off(void)
	{
		LCD_I2C_Start();
			
		LCD_write_byte(0x7C);
		LCD_read_ACK();
		LCD_write_byte(0xB6);
		LCD_read_ACK();
		LCD_write_byte(0xF0);
		LCD_read_ACK();
		LCD_write_byte(0xFe);	// 开启LCD
		LCD_read_ACK();
		LCD_write_byte(0xC8);
		LCD_read_ACK();
		
		
		
		LCD_I2C_Stop();
	
	}


void Seg_san_on(void)
	{
		LCD_I2C_Start();
			
		LCD_write_byte(0x7C);
		LCD_read_ACK();
		LCD_write_byte(0xB6);
		LCD_read_ACK();
		LCD_write_byte(0xF0);
		LCD_read_ACK();
		LCD_write_byte(0xFd);	// 关闭LCD
		LCD_read_ACK();
		LCD_write_byte(0xC8);
		LCD_read_ACK();
		
		
		
		LCD_I2C_Stop();
	
	}




void LCD_I2C_Start(void) //开始信号
{
	SCL_OUT_LCD();
	SDA_OUT_LCD();
	Delayus(0);

	SDA_H_LCD;
	SCL_H_LCD;
	Delayus(0);
	SDA_L_LCD;
	Delayus(0);
	SCL_L_LCD;
}

void LCD_I2C_Stop(void) //停止
{
	SDA_OUT_LCD();
	SDA_L_LCD;
	SCL_L_LCD;
	Delayus(0);
	SDA_H_LCD;
}

void LCD_send_ACK(char b_ACK)     //主机应答ACK，或不应答
{
	SDA_OUT_LCD();
	SCL_L_LCD;
	Delayus(0);
	if(b_ACK)					 //ACK
	{
		SDA_L_LCD; 	   
	}
	else						  //NOACK
	{
		SDA_H_LCD;
	}
	Delayus(0);
	SCL_H_LCD;
	Delayus(0);
	SCL_L_LCD;
	Delayus(0);
}


void LCD_read_ACK(void)    //等待 24C02 回应 ACK
{
	unsigned char t=0;
	SCL_H_LCD;
	Delayus(0);
	while((P26 ==1)&&(t<200))t++;	 //等待ACK，超时跳出
	SCL_L_LCD;
	Delayus(0);
}


void LCD_I2C_init()  //I2C初始化函数，拉高 I2C_SDA 和 I2C_SCL 两条总线
{
	SCL_OUT_LCD();
	SDA_OUT_LCD();

	SDA_H_LCD;
	SCL_H_LCD;
}


void LCD_write_byte(unsigned char date)       //向24C02中写一个字节的数据
{
	unsigned char mask;
	SDA_OUT_LCD();
	SCL_L_LCD;
	for(mask=0x80;mask!=0;mask>>=1)    //从高位到低位依次进行
	{
		
		if((mask&date)==0)
		{
			SDA_L_LCD;
		}
		else
		{
			SDA_H_LCD;
		}
		Delayus(0);
		SCL_H_LCD;
		Delayus(0);
		SCL_L_LCD;
	}

}



unsigned char LCD_read_byte()   //读取一字节，从 24C02 中读取一个字节
{
	unsigned char i=0,read_data=0;
	SDA_IN_LCD();
	SCL_L_LCD;
	Delayus(0);
	SDA_H_LCD;
	Delayus(0);
	for(i=0;i<8;i++)
	{
		SCL_H_LCD;        //I2C_SCL 拉高准备读数据
		Delayus(0);
		read_data=(read_data<<1)|P26 ; //将 I2C_SDA 中的数据读出
		SCL_L_LCD;        //I2C_SCL 拉低数据写完毕
		Delayus(0);
	}
	return read_data;
}

void LCD_write_add(unsigned char address,unsigned char date)    //向 24C02 中写一个字节数据
{
	LCD_I2C_Start();		 //起始信号
	LCD_write_byte(0XA0);	  //发送写指令
	LCD_read_ACK();		//等待应答
	LCD_write_byte(address);	//发送要写入的地址
	LCD_read_ACK();			//等待应答
	LCD_write_byte(date);	  //发送数据
	LCD_read_ACK();		   //等待应答
	LCD_I2C_Stop();		  //停止信号
}


void LCD_write_MultipleByte(unsigned char address,unsigned char length,unsigned char *date)    //数据块写入
{ 
	LCD_I2C_Start();			
	LCD_write_byte(0XA0);		
	LCD_read_ACK();
	LCD_write_byte(address);	 
	LCD_read_ACK();
	while(length--)
	{
		LCD_write_byte(*date++);
		LCD_read_ACK();
		Delayus(0);
	}
	LCD_I2C_Stop();
}


unsigned char LCD_read_add(unsigned char address,char ACK)  //从 24C02 中读出数据
{
	unsigned char date;
	LCD_I2C_Start();		   //第一次起始信号
	LCD_write_byte(0XA0);		//发送写指令
	LCD_read_ACK();			  //等待应答
	LCD_write_byte(address);	  //发送要读取的地址
	LCD_read_ACK();			  //等待应答
	LCD_I2C_Start();			 //第二次起始信号
	LCD_write_byte(0XA1);		 //发送读指令
	LCD_read_ACK();			  //等待应答
	date=LCD_read_byte();		//读数据
	
	LCD_send_ACK(ACK); 	//主机应答ACK或不应答
	
	LCD_I2C_Stop();		  //停止信号
	
	return date;
}



void LCD_read_MultipleByte(unsigned char *temp,unsigned char address,unsigned char data_size)    //读出多个数据
{
	LCD_I2C_Start();
	LCD_write_byte(0XA0);
	LCD_read_ACK();
	LCD_write_byte(address);
	LCD_read_ACK();
	
	LCD_I2C_Start();
	LCD_write_byte(0XA1);
	LCD_read_ACK();
	
	while(data_size--)
	{
		*temp++=LCD_read_byte();
		Delayus(0);
		LCD_send_ACK(data_size);	  //主机应答ACK，当data_size = 0时，发送非应答    主机应答，则继续接受数据；不应答，即表示停止接收
	}
	
	LCD_I2C_Stop();
	
	//return temp;
}






